/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2022 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "i2c.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"
#include "fsmc.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "LCD.h"
#include "openmv.h"
#include "stdio.h"
#include "string.h"
#include "touch.h"
#include "24cxx.h"
#include "ultra.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
uint8_t rx_data=0;
uint8_t bluetooth_rx_buffer=0;
uint8_t inputstate=0;  //�???????0代表当前输入距离，为1代表当前输入角度,�???????2代表全部输入完成�???????

uint16_t indistance=0;
uint16_t inangel1=0;
uint16_t inangle2=0;

uint32_t chooseflag=0;   //chooseflag=1说明选择了调试模式，chooseflag=2说明选择基础部分

uint16_t pwmval1=500;
uint16_t pwmval2=500;

uint8_t realangle=0;
/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
#ifdef __GNUC__
	#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
	#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif

PUTCHAR_PROTOTYPE
{
	HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
	return ch;
}
/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */
  HAL_Delay(40);  //给一个缓�????????????????????
  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_FSMC_Init();
  MX_TIM7_Init();
  MX_I2C1_Init();
  MX_USART3_UART_Init();
  MX_USART1_UART_Init();
  MX_TIM3_Init();
  MX_TIM2_Init();
  MX_USART2_UART_Init();
  /* USER CODE BEGIN 2 */

  /**************************LCD初始化界面，按下KEY1则跳转数据交互界�??????????**************************/
  LCD_Init();
  ShowInitPage();
  while(1)
  {
	  if(HAL_GPIO_ReadPin(T_PEN_GPIO_Port,T_PEN_Pin)==0)
		  break;
  }
  HAL_Delay(100);
  LCD_Clear(WHITE);
  ShowChoosePage();
  /**************************LCD初始化界面，按下KEY1则跳转数据交互界�??????????***************************/

  /**************************使能定时器输入中断，用于启动超声波测�??????????*******************************/
  HAL_TIM_Base_Start_IT(&htim3);
  HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_1);
  /**************************使能定时器输入中断，用于启动超声波测�??????????********************************/

  /*****************************串口3使能接收中断，用于接收Openmv数据******************************/
//  HAL_UART_Receive_IT(&huart3,&rx_data,1);  //�????????????????启中断�??
  /*****************************串口3使能接收中断，用于接收Openmv数据******************************/

  /*****************************舵机控制初始�??????******************************/
  HAL_TIM_Base_Start(&htim2);
  HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);
  HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);
  /*****************************舵机控制初始�??????******************************/
  TouchChoose();
  HAL_Delay(50);
  /******************************串口2使能接收中断，用于接收手机传来的蓝牙数据***********************/
  HAL_UART_Receive_IT(&huart2,&bluetooth_rx_buffer,1);
  /******************************串口2使能接收中断，用于接收手机传来的蓝牙数据***********************/
  LCD_Clear(WHITE);
  ShowButton();

  TIM2->CCR1=1750;
  HAL_Delay(2000);
  TIM2->CCR2=2000;

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	 tp_dev.scan(0);

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
     if(inputstate==3)
     {
    	 HAL_GPIO_WritePin(LED_GPIO_Port,LED_Pin,0);
    	 pwmval1=(uint16_t)(7.778*inangel1+1050);  //底部舵机
    	 pwmval2=(uint16_t)(6.667*inangle2+2000);   //顶部舵机
    	 TIM2->CCR1=pwmval1;
    	 HAL_Delay(2500);
    	 TIM2->CCR2=pwmval2;
    	 HAL_Delay(2500);
    	 inputstate=4;  //使下次不在进�????
     }
     else if(inputstate==4)
     {
    	 HAL_GPIO_WritePin(Relayer_GPIO_Port,Relayer_Pin,1);   //充电
    	 inputstate=5;
     }
     else if(inputstate==5)
     {
    	 tp_dev.scan(0);
    	 if(tp_dev.x>1488&&tp_dev.x<2513&&tp_dev.y>2088&&tp_dev.y<2713)
    	 {
    		 HAL_GPIO_WritePin(Relayer2_GPIO_Port,Relayer2_Pin,1);   //放电
    		 HAL_GPIO_WritePin(Relayer_GPIO_Port,Relayer_Pin,0);   //关闭充电回路防止再次充电
    	 }
     }

//     IsRelayerDown();
//     IsRelayer2Down();
	 /***********************超声波测距程�??????????************************/
//     Read_Distance();
	 /************************************************************/
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  if(huart->Instance==USART3)   //判断若是串口3收到数据触发中断
   {
	  uint8_t temp=0;   //已经测试进入中断成功
      temp=rx_data;
      Openmv_Receive_Data(temp);  //在该函数中完成对Cx,Cy的赋值�??
      HAL_UART_Receive_IT(&huart3,&rx_data,1);  //使能串口接收中断，接收的是一个十六位数据�??????????????
   }
  else if(huart->Instance==USART2)   //判断若是串口2蓝夜接收�?
  {
	  if(chooseflag==1)   //选择了调试部分
	  {
		  static uint8_t data=0;
		  if(inputstate==0&&bluetooth_rx_buffer!=0xFF)
		  {
			  data=bluetooth_rx_buffer;
			  LCD_Fill(150,420,189,445,GREEN);
			  POINT_COLOR=RED;
			  LCD_ShowNum(150,420,data,GetPlace(data),24);
		  }
		  else if(inputstate==0&&bluetooth_rx_buffer==0xFF)
		  {
			  inputstate=1;
			  LCD_ShowString(230,420,72,24,24,"Finish");  //给距离表示输入完成标志�??
			  inangle2=data;
		  }
		  HAL_UART_Receive_IT(&huart2,&bluetooth_rx_buffer,1);
	  }
	  else if(chooseflag==2)      //选择了基础部分
	  {
		  static uint16_t bluetooth_rx_data=0;
		  if(inputstate==0&&bluetooth_rx_buffer!=0xFF)   //说明接受的是距离值�??
		  {
			  bluetooth_rx_data=bluetooth_rx_buffer*2;
			  LCD_Fill(150,420,189,445,WHITE);
			  LCD_ShowNum(150,420,bluetooth_rx_data,GetPlace(bluetooth_rx_data),24);  //显示距离�???????
		  }
		  else if(inputstate==0&&bluetooth_rx_buffer==0xFF)   //输入0xFF代表输入距离完成，先输入距离再输入角度�??
			{
			  inputstate=1;  //转置为角度输入�??
			  POINT_COLOR=BLUE;
			  LCD_ShowString(230,420,72,24,24,"Finish");  //给距离表示输入完成标志�??
			  POINT_COLOR=BLACK;
			  indistance=bluetooth_rx_data;  //完成赋�?��??
			}
		  else if(inputstate==1&&bluetooth_rx_buffer!=0xFF)  //代表当前输入的是角度
		  {
			  bluetooth_rx_data=bluetooth_rx_buffer;
			  LCD_Fill(132,390,169,415,WHITE);  //底部舵机数据部分清零
			  LCD_ShowNum(132,390,bluetooth_rx_data,GetPlace(bluetooth_rx_data),24);  //输出底部舵机角度
		  }
		  else if(inputstate==1&&bluetooth_rx_buffer==0xFF)
		  {
			  inputstate=2;   //角度也赋值完�???????
			  POINT_COLOR=BLUE;
			  LCD_ShowString(192,390,72,24,24,"Finish");
			  POINT_COLOR=BLACK;
			  inangel1=bluetooth_rx_data;
		  }
		  else if(inputstate==2&&bluetooth_rx_buffer!=0xFF)
		  {
			  bluetooth_rx_data=bluetooth_rx_buffer;
			  LCD_Fill(132,360,169,385,WHITE);   //顶部舵机数据部分清零
			  LCD_ShowNum(132,360,bluetooth_rx_data,GetPlace(bluetooth_rx_data),24);  //输出顶部舵机角度
		  }
		  else if(inputstate==2&&bluetooth_rx_buffer==0xFF)
		  {
			  inputstate=3;
			  POINT_COLOR=BLUE;
			  LCD_ShowString(192,360,72,24,24,"Finish");
			  POINT_COLOR=BLACK;
			  inangle2=bluetooth_rx_data;
		  }
		  HAL_UART_Receive_IT(&huart2,&bluetooth_rx_buffer,1);
	  }
	  else if(chooseflag==3)    //设置
	  {
		  static uint16_t angle_rx=0;
		  if(inputstate==0&&bluetooth_rx_buffer!=0xFF)
		  {
			  angle_rx=bluetooth_rx_buffer;
			  LCD_ShowNum(0, 0,angle_rx,GetPlace(angle_rx),24);
		  }
		  else if(inputstate==0&&bluetooth_rx_buffer==0xFF)
		  {
			  inputstate=1;
			  realangle=angle_rx;
//			  Stop(angle_rx);
		  }
		  HAL_UART_Receive_IT(&huart2,&bluetooth_rx_buffer,1);
	  }
  }
}

void IsRelayerDown()
{
	if(HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin)==0)
	{
		HAL_Delay(10);  //按键消抖
		if(HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin)==0)
			HAL_GPIO_WritePin(Relayer_GPIO_Port,Relayer_Pin,1);   //充电继电器打�????
	}
	else
	{
		HAL_Delay(10);  //按键消抖
		HAL_GPIO_WritePin(Relayer_GPIO_Port,Relayer_Pin,0);   //充电继电器关�????
	}
}

void IsRelayer2Down()
{
	if(HAL_GPIO_ReadPin(KEY0_GPIO_Port,KEY0_Pin)==0)
	{
		HAL_Delay(10);  //按键消抖
		if(HAL_GPIO_ReadPin(KEY0_GPIO_Port,KEY0_Pin)==0)
			HAL_GPIO_WritePin(Relayer2_GPIO_Port,Relayer2_Pin,1);   //放电继电器打�????
	}
	else
	{
		HAL_Delay(10);  //按键消抖
		HAL_GPIO_WritePin(Relayer2_GPIO_Port,Relayer2_Pin,0);   //充电继电器打�????
	}
}

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
